-
Notifications
You must be signed in to change notification settings - Fork 2
chore: migrate from styled components to tailwind #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
- Also update @kleros/ui-components-library to latest version
❌ Deploy Preview for curate-v2 failed. Why did it fail? →
|
WalkthroughReplaces styled-components with Tailwind/className across the web frontend, adds Tailwind tooling and global.css, upgrades Changes
Sequence Diagram(s)sequenceDiagram
participant App as App
participant ThemeProv as ThemeProvider
participant Doc as document.documentElement
participant ToggleCtx as ToggleThemeProvider
participant UI as UI Component
App->>ThemeProv: mount ThemeProvider(children)
ThemeProv->>ThemeProv: load theme from localStorage (default "dark")
ThemeProv->>Doc: add/remove "dark" CSS class
ThemeProv->>ToggleCtx: provide [theme, toggleTheme]
UI->>ToggleCtx: consume [theme, toggleTheme]
UI->>UI: render using cn(...) (clsx + twMerge)
UI->>ThemeProv: user triggers toggleTheme()
ThemeProv->>ThemeProv: persist theme and update DOM class
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related issues
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
web/src/global.css (1)
60-62: Consider reducing !important usage.The
!importantdeclarations on lines 61 and 147 override library defaults for ReactModal and Toastify. While sometimes necessary for third-party library overrides, consider if these can be achieved through higher CSS specificity instead.If the library CSS is loaded before your global styles, you may be able to increase specificity without
!important:/* Instead of: */ .ReactModal__Overlay { background-color: #1b003fcc !important; } /* Try: */ .ReactModal__Overlay.ReactModal__Overlay { background-color: #1b003fcc; }Also applies to: 145-148
web/src/context/ThemeProvider.tsx (1)
8-8: Improve type safety for theme values.The theme is currently typed as
string, which allows any string value. This should be constrained to the valid theme values for better type safety and developer experience.Apply this diff to add proper typing:
+type Theme = "light" | "dark"; + const ThemeProvider: React.FC<{ children: React.ReactNode; }> = ({ children }) => { - const [theme, setTheme] = useLocalStorage<string>("theme", "dark"); + const [theme, setTheme] = useLocalStorage<Theme>("theme", "dark");
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (11)
web/package.json(2 hunks)web/src/app.tsx(3 hunks)web/src/context/StyledComponentsProvider.tsx(0 hunks)web/src/context/ThemeProvider.tsx(1 hunks)web/src/global.css(1 hunks)web/src/styles/commonStyles.ts(0 hunks)web/src/styles/customScrollbar.ts(0 hunks)web/src/styles/global-style.ts(0 hunks)web/src/styles/landscapeStyle.ts(0 hunks)web/src/styles/themes.ts(0 hunks)web/vite.config.js(2 hunks)
💤 Files with no reviewable changes (6)
- web/src/styles/global-style.ts
- web/src/styles/landscapeStyle.ts
- web/src/styles/themes.ts
- web/src/styles/commonStyles.ts
- web/src/styles/customScrollbar.ts
- web/src/context/StyledComponentsProvider.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (6)
web/vite.config.js (1)
5-5: LGTM! Tailwind v4 Vite integration is correct.The Tailwind CSS integration follows the standard pattern for v4 with Vite using the
@tailwindcss/viteplugin.Also applies to: 32-32
web/src/global.css (1)
1-20: LGTM! Tailwind v4 @theme directive and imports are correctly structured.The global CSS setup follows Tailwind v4 best practices: importing the UI library theme, importing Tailwind, and defining custom design tokens via the
@themedirective. The token definitions are comprehensive and well-organized.web/package.json (2)
78-78: LGTM! Tailwind CSS dependencies are correctly added.Both
tailwindcssand@tailwindcss/viteare on the same version (4.1.16), which ensures consistency. The@tailwindcss/vitepackage is appropriately placed in bothdependenciesanddevDependenciesfor build tooling access.Also applies to: 107-107
73-73: Manually verify component compatibility after Tailwind migration to v3.6.0.The upgrade to v3.6.0 involved a major migration from styled-components to Tailwind CSS. The library was migrated to Tailwind CSS, which includes changes to component styling and theming. Tailwind is already configured in the project (v4.1.16).
The codebase uses 23+ components from the library across 40+ files, including several internal components prefixed with underscore (_TimelineItem1, _IItem1). However, no public changelog documents specific breaking changes and component API modifications for v3.6.0.
Actions required:
- Test all component usages throughout the application (run tests and manual QA)
- Verify visual regressions from CSS token/spacing changes
- Confirm internal components (_TimelineItem1, _IItem1) remain stable and exported in v3
- Check for any prop renames or removed component APIs against the library's Storybook or GitHub repository
web/src/context/ThemeProvider.tsx (1)
10-22: LGTM! Dark mode implementation is correct.The theme toggling logic and the
useEffectthat applies thedarkclass todocument.documentElementcorrectly implements Tailwind's class-based dark mode strategy. The implementation will work seamlessly with Tailwind'sdark:variant.web/src/app.tsx (1)
4-4: LGTM! Theme provider migration is correctly implemented.The migration from
StyledComponentsProviderto the newThemeProvideris clean and correct. Theglobal.cssimport is properly placed early in the file, and theThemeProvidercorrectly wraps the entire application as the outermost provider to ensure theme context is available throughout the component tree.Also applies to: 7-7, 26-26, 59-59
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
web/src/context/Web3Provider.tsx (1)
62-62: Consider adding the brand color to the theme system for maintainability.The hardcoded color
#4D00B4is correct—it matches the primary brand color used throughout SVG assets. However, since the codebase has migrated to Tailwind with a theme system (defined inweb/src/global.css), consider adding this color to the@themeblock for consistency and easier maintenance:/* In web/src/global.css @theme block */ --color-primary: #4D00B4;Then reference it in Web3Provider:
"--w3m-color-mix": "var(--color-primary)",This keeps brand colors centralized and easier to maintain across the codebase. The color itself doesn't need to change between light/dark modes—this is a brand constant, not a theme-dependent color.
web/src/layout/index.tsx (1)
22-22: Consider extracting the hardcoded spacing value.The hardcoded
pt-[70px]value appears to offset the ToastContainer from the header. For better maintainability and theme consistency, consider defining this as a CSS variable or Tailwind theme extension that matches the header height.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
web/global.d.ts(1 hunks)web/src/context/Web3Provider.tsx(1 hunks)web/src/layout/index.tsx(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/index.tsx (1)
23-23: Consider adding dark mode variant.The background class
bg-klerosUIComponentsLightBackgroundimplies a light theme background. Based on the PR's ThemeProvider that toggles a document-leveldarkclass, consider whether this element needs a corresponding dark mode variant (e.g.,dark:bg-klerosUIComponentsDarkBackground).web/global.d.ts (1)
1-12: LGTM!The removal of styled-components module augmentation is appropriate for the Tailwind migration. The file correctly preserves the necessary ambient declarations for SVG and PNG imports while maintaining proper module structure with the
export {}statement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 20
🧹 Nitpick comments (3)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1)
45-45: Consider using standard spacing scale instead of arbitrary value.The arbitrary value
mb-[10px]works correctly in Tailwind v4, but using the standard spacing scale improves consistency across the codebase. Since 10px equals 2.5rem (2.5 × 4px), consider usingmb-2.5instead.- <label className="flex justify-between mb-[10px]">{contactLabel}</label> + <label className="flex justify-between mb-2.5">{contactLabel}</label>web/src/layout/Header/Logo.tsx (2)
8-13: Remove unnecessary whitespace literal.The
{" "}on line 9 serves no purpose and can be removed for cleaner code.Apply this diff:
<div className="flex flex-row items-center gap-4"> - {" "} <Link to={"/"}> <CurateLogo className="transition duration-100 max-h-12 w-auto hover:fill-white/75" /> </Link> </div>
10-12: Add accessible label for the logo link.The logo link lacks descriptive text for screen readers. Add an
aria-labelto improve accessibility.Apply this diff:
- <Link to={"/"}> + <Link to={"/"} aria-label="Home"> <CurateLogo className="transition duration-100 max-h-12 w-auto hover:fill-white/75" /> </Link>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (23)
web/src/app.tsx(3 hunks)web/src/components/ConnectWallet/AccountDisplay.tsx(2 hunks)web/src/components/InfoCard.tsx(1 hunks)web/src/components/LightButton.tsx(1 hunks)web/src/components/Overlay.tsx(1 hunks)web/src/components/OverlayPortal.tsx(1 hunks)web/src/context/ThemeProvider.tsx(1 hunks)web/src/global.css(1 hunks)web/src/layout/Header/DesktopHeader.tsx(1 hunks)web/src/layout/Header/Logo.tsx(1 hunks)web/src/layout/Header/index.tsx(1 hunks)web/src/layout/Header/navbar/DappList.tsx(1 hunks)web/src/layout/Header/navbar/Debug.tsx(2 hunks)web/src/layout/Header/navbar/Explore.tsx(2 hunks)web/src/layout/Header/navbar/Menu/Help.tsx(1 hunks)web/src/layout/Header/navbar/Menu/Settings/General.tsx(1 hunks)web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx(1 hunks)web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx(1 hunks)web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx(3 hunks)web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx(1 hunks)web/src/layout/Header/navbar/Menu/Settings/index.tsx(1 hunks)web/src/layout/Header/navbar/Menu/index.tsx(1 hunks)web/src/layout/Header/navbar/Product.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- web/src/context/ThemeProvider.tsx
- web/src/app.tsx
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsxweb/src/layout/Header/navbar/Menu/Settings/index.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/index.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx
📚 Learning: 2024-11-04T13:29:55.971Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/context/AtlasProvider.tsx:176-193
Timestamp: 2024-11-04T13:29:55.971Z
Learning: In the `web/src/context/AtlasProvider.tsx` file of the React application, the `authoriseUser` function handles session invalidation and delegates error handling and user notifications to the functions that invoke it. Therefore, adding error notifications within `authoriseUser` is unnecessary.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsxweb/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
Applied to files:
web/src/global.css
🧬 Code graph analysis (5)
web/src/layout/Header/navbar/Debug.tsx (1)
web/src/consts/index.ts (2)
RELEASE_VERSION(12-12)GIT_URL(11-11)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (2)
web/src/components/EnsureChain.tsx (1)
EnsureChain(10-14)web/src/components/ConnectWallet/AccountDisplay.tsx (3)
IdenticonOrAvatar(16-34)AddressOrName(40-50)ChainDisplay(52-56)
web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (2)
web/src/layout/Header/navbar/index.tsx (1)
ISettings(54-56)web/src/components/EnsureChain.tsx (1)
EnsureChain(10-14)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx (1)
web/src/utils/date.ts (1)
timeLeftUntil(43-69)
web/src/layout/Header/index.tsx (1)
web/src/utils/getGraphqlUrl.ts (1)
getGraphqlUrl(3-7)
🔇 Additional comments (12)
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx (1)
45-52: Migration looks clean, but verify label-input association for accessibility.The migration from styled-components to Tailwind classes is well-executed. However, the
<label>on line 45 lacks ahtmlForattribute to associate it with the input field. If theFieldcomponent renders an input element, ensure proper label-input association for accessibility.Consider adding a
htmlForattribute if the Field component exposes an id:- <label className="flex justify-between mb-[10px]">{contactLabel}</label> + <label htmlFor="contact-input" className="flex justify-between mb-[10px]">{contactLabel}</label> <Field className="flex flex-col items-center w-full" + id="contact-input" variant={fieldVariant}Alternatively, if the
Fieldcomponent from@kleros/ui-components-libraryhandles accessibility internally or doesn't support id props, you may disregard this suggestion.web/src/layout/Header/navbar/DappList.tsx (1)
98-98: LGTM!The h1 header uses standard Tailwind utility classes correctly.
web/src/layout/Header/navbar/Menu/Help.tsx (1)
52-53: The breakpoint is already properly configured—no action needed.The custom
landscape-900:breakpoint is correctly defined inweb/src/global.cssusing Tailwind v4's@themeblock with the--breakpoint-landscape-900: 900px;variable, which automatically creates the responsive modifier. The review comment incorrectly assumes traditional Tailwind configuration (JS/TS config file), which is not applicable to Tailwind v4's CSS-first approach. The code at lines 52-53 in Help.tsx correctly uses this pre-configured breakpoint.Likely an incorrect or invalid review comment.
web/src/layout/Header/navbar/Debug.tsx (1)
5-20: LGTM!The migration from styled-components to className-based styling is implemented correctly. The arbitrary font-family syntax
font-[Roboto_Mono,monospace]is proper Tailwind v4 usage.web/src/components/Overlay.tsx (1)
1-5: LGTM!Clean conversion from styled-component to a functional component with Tailwind classes. The
bg-black-low-opacitycustom color should be defined in your theme configuration.web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx (1)
36-49: LGTM!Successful migration from styled-components to utility classes. The SVG fill and layout classes are properly applied.
web/src/global.css (2)
1-67: Well-structured Tailwind v4 integration.The global stylesheet properly:
- Imports the UI library theme and Tailwind v4 using the new
@importsyntax- Defines custom theme tokens via
@themedirective- Implements accessible focus management with
:focus-visible(addressing the previous review concern)The focus styling (lines 60-67) now correctly preserves keyboard navigation accessibility while removing focus outlines for mouse users.
138-142: Verify browser support for CSS nesting.The nested selector syntax
ul { li { ... } }requires modern browsers. Based on your Tailwind v4 adoption (which targets Chrome 111+, Safari 16.4+, Firefox 128+), this should be supported, but confirm this aligns with your browser compatibility requirements.web/src/layout/Header/index.tsx (1)
12-33: LGTM! Clean migration to Tailwind v4 syntax.The header structure correctly uses Tailwind v4 features including advanced selector syntax for StatusBanner styling and CSS variables for theme integration. The sticky positioning and backdrop blur effects are properly configured.
web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)
20-49: LGTM! Proper use of Tailwind v4 advanced features.The component correctly uses Tailwind v4's advanced selector syntax (
[&>label],[&_label]) and pseudo-element utilities (before:content-['']) to style nested elements. The layout structure is clean and maintains the original functionality.web/src/layout/Header/DesktopHeader.tsx (1)
43-43: LGTM! Correct Tailwind v4 important modifier syntax.The important modifier is correctly placed at the end of the utility class (
fill-white!), which is the proper Tailwind v4 syntax.web/src/layout/Header/navbar/Menu/Settings/Notifications/index.tsx (1)
18-30: LGTM!The migration to Tailwind utilities is well-executed. The flexbox layout structure correctly preserves the component's intended design with proper centering and spacing.
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
Outdated
Show resolved
Hide resolved
web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
♻️ Duplicate comments (1)
web/src/components/ConnectWallet/AccountDisplay.tsx (1)
78-80: Fix merged utility class separator.The concatenated strings still miss a trailing space before
landscape-900:hidden, so the output becomesbefore:ml-[3px]landscape-900:hiddenand Tailwind drops both utilities. Add the separator (or switch to a template literal) so each class stays intact.- "before:content-[''] before:w-2 before:h-2 before:rounded-[50%] before:bg-klerosUIComponentsSuccess before:my-0 before:mr-[13px] before:ml-[3px]" + + "before:content-[''] before:w-2 before:h-2 before:rounded-[50%] before:bg-klerosUIComponentsSuccess before:my-0 before:mr-[13px] before:ml-[3px] " +
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
web/src/components/ConnectWallet/AccountDisplay.tsx(2 hunks)web/src/components/InfoCard.tsx(1 hunks)web/src/components/LightButton.tsx(1 hunks)web/src/global.css(1 hunks)web/src/layout/Header/DesktopHeader.tsx(1 hunks)web/src/layout/Header/Logo.tsx(1 hunks)web/src/layout/Header/navbar/DappList.tsx(1 hunks)web/src/layout/Header/navbar/Explore.tsx(2 hunks)web/src/layout/Header/navbar/Menu/Help.tsx(1 hunks)web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx(3 hunks)web/src/layout/Header/navbar/Menu/Settings/index.tsx(1 hunks)web/src/layout/Header/navbar/Menu/index.tsx(1 hunks)web/src/layout/Header/navbar/Product.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
- web/src/components/InfoCard.tsx
- web/src/layout/Header/navbar/Explore.tsx
- web/src/layout/Header/Logo.tsx
- web/src/components/LightButton.tsx
- web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
Applied to files:
web/src/global.css
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/Header/navbar/Menu/Help.tsx (1)
48-69: LGTM! Previous issues resolved.The Tailwind utility classes are now correct, and the className concatenation includes proper spacing.
web/src/layout/Header/navbar/Menu/Settings/index.tsx (1)
39-39: Previous issues resolved.The invalid
width-[calc(...)]utility has been corrected tow-[calc(...)].
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
🧹 Nitpick comments (1)
web/src/layout/Header/navbar/Product.tsx (1)
39-39: Consider removing unnecessaryflexclass.The
<small>element contains only text and usestext-centerfor alignment. Theflexclass appears unnecessary sincetext-centeralone handles text alignment for inline content.- <small className="flex font-normal text-center leading-[19px]">{text}</small> + <small className="font-normal text-center leading-[19px]">{text}</small>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
web/src/components/LightButton.tsx(1 hunks)web/src/layout/Header/navbar/DappList.tsx(1 hunks)web/src/layout/Header/navbar/Explore.tsx(2 hunks)web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx(3 hunks)web/src/layout/Header/navbar/Menu/Settings/index.tsx(1 hunks)web/src/layout/Header/navbar/Menu/index.tsx(1 hunks)web/src/layout/Header/navbar/Product.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- web/src/layout/Header/navbar/DappList.tsx
- web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx
- web/src/components/LightButton.tsx
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/index.tsx
📚 Learning: 2024-11-04T13:41:31.226Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:126-126
Timestamp: 2024-11-04T13:41:31.226Z
Learning: In `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, the `isUndefined` function effectively handles `null` or `undefined` values. Therefore, using the non-null assertion `!` on `user?.emailUpdateableAt` when calling `timeLeftUntil(user?.emailUpdateableAt!)` is acceptable, as potential `null` or `undefined` cases are already managed.
Applied to files:
web/src/layout/Header/navbar/Menu/Settings/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (4)
web/src/layout/Header/navbar/Explore.tsx (2)
17-18: LGTM! Clean active route detection.The
isActivehelper correctly handles both the root path (exact match) and nested routes (first segment comparison), which prevents false positives in navigation highlighting.
36-49: Custom utilities are properly configured—no changes required, but consider adding @source directive.The className structure is correct and all custom utilities are properly defined in your Tailwind v4 setup:
text-klerosUIComponentsPrimaryText,text-primary-text-73,text-white-73are configured via CSS variables in the@themeblocklandscape-900:breakpoint is defined as--breakpoint-landscape-900: 900px- All utilities are actively used and functional throughout the codebase
Based on the learning context, consider adding the
@sourcedirective inweb/src/global.cssto explicitly tell Tailwind to scan the@kleros/ui-components-libraryfor utility classes:@source "../node_modules/@kleros/ui-components-library"; @import "@kleros/ui-components-library/theme.css"; @import "tailwindcss";This ensures Tailwind can generate utilities from CSS variables in the external library, though the current setup appears to be working without it.
web/src/layout/Header/navbar/Product.tsx (1)
16-25: Previous critical issues successfully resolved!All three issues from the previous review have been properly addressed:
- ✅ Security:
rel="noopener noreferrer"added- ✅ Styling: className construction fixed and dynamic width moved to style prop
- ✅ This segment demonstrates proper Tailwind v4 migration pattern
web/src/layout/Header/navbar/Menu/index.tsx (1)
37-37: Clean responsive layout structure.The flex layout with responsive breakpoint is well-structured for converting the menu from vertical to horizontal orientation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/src/layout/Header/navbar/index.tsx (1)
2-2: Remove unused styled-components import.The
styledimport is no longer used after migrating to Tailwind utility classes.Apply this diff to remove the unused import:
-import styled from "styled-components";
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
web/src/layout/Header/MobileHeader.tsx(1 hunks)web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx(2 hunks)web/src/layout/Header/navbar/index.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/FormContact.tsx
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/layout/Header/navbar/index.tsx (1)
web/src/layout/Header/navbar/Menu/Settings/General.tsx (1)
DisconnectWalletButton(7-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/layout/Header/navbar/index.tsx (1)
59-66: LGTM! Wallet container refactoring is correct.The replacement of styled components with Tailwind flex utilities is appropriate, and the wrapper div for vertical alignment maintains the intended layout.
web/src/layout/Header/MobileHeader.tsx (1)
29-29: Custom breakpoint is properly configured.The
landscape-900breakpoint is defined as a CSS variable inweb/src/global.css(line 21:--breakpoint-landscape-900: 900px;) and is successfully used across the codebase in multiple files (DesktopHeader, DappList, Explore, Menu, Settings, LightButton, AccountDisplay). The consistent usage throughout the project confirms proper Tailwind integration.However, the icon-only button on line 33 lacks accessibility attributes — add
aria-labelortitleto the LightButton sincetext="":<LightButton className="p-0 [&_.button-svg]:mr-0" text="" Icon={HamburgerIcon} onClick={toggleIsOpen} aria-label="Toggle menu" />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (4)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (2)
45-52: Consider removing redundant bottom margin.The
mb-2class on the image may be redundant since the parent container at line 40 already usesgap-4for spacing between flex items.<img width={125} height={125} - className="object-contain mb-2" + className="object-contain" src={imageSrc} onError={() => setImageSrc(getIpfsUrl(DEFAULT_LIST_LOGO))} alt="List Img" />
42-42: Maintain consistency with image styling.If you remove the
mb-2from the image element (see previous comment), ensure the Skeleton placeholder matches the same styling for visual consistency.- <Skeleton width={125} height={125} borderRadius="62.5px" className="mb-2" /> + <Skeleton width={125} height={125} borderRadius="62.5px" />web/src/pages/AllLists/RegistryDetails/Tabs.tsx (2)
18-18: Clarify the necessity ofcontent: nullfields.Both TABS entries include
content: null, but the current implementation uses a callback-based approach for tab changes (line 58) rather than rendering tab content directly. If thecontentproperty is not required by theTabsComponentAPI, these fields add unnecessary noise.Please confirm whether the
contentproperty is required by@kleros/ui-components-libraryv3.6.0's TabsComponent. The same web search from the previous comment will help verify this.Also applies to: 27-27
54-60: Clean callback-based tab implementation.The refactored TabsComponent usage correctly implements callback-based navigation. The callback signature ignoring the first parameter with
_is appropriate, and the integration withhandleTabChangemaintains the existing navigation behavior.Consider adding TypeScript typing for the
TABSarray to improve type safety and make the expected structure more explicit:+interface TabItem { + id: number; + text: string; + value: number; + Icon: React.FC; + path: string; + identifier: string; + content: null | React.ReactNode; +} + -const TABS = [ +const TABS: TabItem[] = [
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx(1 hunks)web/src/components/InformationCards/RegistryInformationCard/index.tsx(4 hunks)web/src/pages/AllLists/RegistryDetails/Tabs.tsx(2 hunks)web/src/pages/AllLists/RegistryDetails/index.tsx(2 hunks)web/src/pages/AllLists/index.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- web/src/pages/AllLists/index.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.
Applied to files:
web/src/pages/AllLists/RegistryDetails/Tabs.tsx
🧬 Code graph analysis (3)
web/src/pages/AllLists/RegistryDetails/Tabs.tsx (2)
web/src/utils/uri.ts (1)
encodeListURIFilter(4-10)web/src/consts/filters.ts (1)
List_filters(5-11)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (4)
web/src/utils/index.ts (1)
isUndefined(5-5)web/src/utils/getIpfsUrl.ts (1)
getIpfsUrl(4-8)web/src/consts/index.ts (1)
DEFAULT_LIST_LOGO(23-23)web/src/consts/chains.ts (1)
SUPPORTED_CHAINS(9-11)
web/src/components/InformationCards/RegistryInformationCard/index.tsx (2)
web/src/utils/index.ts (1)
cn(44-46)web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
Policies(21-59)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (12)
web/src/pages/AllLists/RegistryDetails/index.tsx (1)
45-69: LGTM! Clean migration to Tailwind.The replacement of the styled
Containerwith adivusingflex flex-colis correct and follows standard Tailwind patterns for vertical layouts. The change is purely structural with no impact on functionality.web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (3)
35-38: LGTM: Responsive flex layout implemented correctly.The combination of
flex-wrapwithlg:flex-nowrapensures proper responsive behavior, and the responsive padding usingresponsiveSizemaintains consistency with the existing codebase patterns.
63-66: LGTM: Breakpoint aligns with library configuration.The
responsiveSize(24, 32, 900)correctly uses 900px to match theLG_BREAKPOINToverride from@kleros/ui-components-library.Based on learnings
69-76: LGTM: Anchor styling correctly applied.The
text-klerosUIComponentsPrimaryBlueutility class properly styles the link, and the structure within theCopiablecomponent is maintained correctly.web/src/components/InformationCards/RegistryInformationCard/index.tsx (5)
11-11: LGTM: Correct usage of cn utility for className composition.The
cnutility is properly imported and used to merge the optionalclassNameprop with base classes, allowing for flexible external styling while maintaining core styles.Also applies to: 51-51
30-30: LGTM: Public API extended appropriately.Adding the optional
classNameprop enables flexible external styling, which is a standard pattern for utility-class-based component libraries.
53-55: LGTM: Warning message correctly styled.The warning paragraph uses appropriate utility classes and theme-aware CSS variables for consistent styling. The conditional rendering based on validation results is correctly implemented.
69-72: LGTM: Divider correctly implemented.The
hrelement withh-pxandborder-noneproperly replaces the styled Divider component. The responsive margin logic usingresponsiveSizemaintains consistency with the rest of the codebase.
73-88: LGTM: Bottom section layout correctly structured.The flex-based layout with
flex-wrapandjustify-betweenprovides appropriate responsive behavior. The nested structure maintains logical grouping of the submitter information and action button.web/src/pages/AllLists/RegistryDetails/Tabs.tsx (3)
8-8: LGTM: clsx import aligns with Tailwind migration.The addition of clsx is appropriate for composing className strings in the Tailwind-based approach.
56-56: Verify the complex Tailwind selector behaves as intended.The className includes
*:[&_svg]:mr-2, which is a complex selector attempting to add right margin to SVG elements within direct children. While this syntax is valid in Tailwind, it's worth verifying that it produces the desired spacing for tab icons.If this doesn't work as expected, consider using a simpler approach by adding the margin class directly to the Icon components within each tab item, or verify the rendered output to ensure proper icon spacing.
12-12: Verify if bothidandvaluefields are necessary.Both TABS entries now include
idandvaluefields with identical values (0 and 1 respectively). This appears redundant and could cause confusion about which field should be used for tab identification.Please verify whether the
@kleros/ui-components-libraryv3 TabsComponent requires both fields. If only one is needed, consider removing the redundant field:Also applies to: 21-21
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (1)
63-66: Consider consolidating gap utilities for clarity.The
gap-8class on line 64 sets both row and column gaps to 32px, but line 65's inlinecolumnGapstyle overrides it with responsive values. While this works, mixing Tailwind utilities with inline styles for the same property can be confusing for maintainability.If the
responsiveSizefunction provides custom interpolation that Tailwind's responsive utilities don't support, this is acceptable. Otherwise, consider using Tailwind's responsive gap utilities (e.g.,gap-6 lg:gap-8) for consistency.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (4)
web/src/utils/index.ts (1)
isUndefined(5-5)web/src/utils/getIpfsUrl.ts (1)
getIpfsUrl(4-8)web/src/consts/index.ts (1)
DEFAULT_LIST_LOGO(23-23)web/src/consts/chains.ts (1)
SUPPORTED_CHAINS(9-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (2)
35-62: Successful migration to Tailwind utilities.The layout structure and conditional rendering with loading skeletons look correct. The image properly uses
object-containfor aspect ratio preservation, and all elements use appropriate Tailwind utility classes. Good job addressing the previous review feedback—the paragraph element (line 60) no longer has the unnecessary underline utilities.
69-76: Anchor styling is correct.The anchor element appropriately uses
no-underline hover:underlineclasses (unlike paragraph elements), and the external link properly includesrel="noreferrer"for security. The custom color classtext-klerosUIComponentsPrimaryBluecorrectly references the theme from @kleros/ui-components-library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/src/components/HistoryDisplay/index.tsx (1)
56-126: Fix the return type—function returns an array, not a single item.The function signature declares the return type as
TimelineItem(singular), but the function body creates and returnshistoryItems: TimelineItem[](array) on line 125. The caller on line 30 spreads the result withacc.push(...history), confirming it expects an array. This type mismatch will cause TypeScript compilation errors.Apply this diff to fix the return type:
const constructItemsFromRequest = ( request: RequestDetailsFragment, isLightTheme: boolean, isItem?: boolean -): TimelineItem => { +): TimelineItem[] => { const historyItems: TimelineItem[] = [];
🧹 Nitpick comments (6)
web/src/pages/AllLists/RegistryDetails/List/index.tsx (1)
59-63: Tailwind list container and Skeleton fallback look good; confirmjustify-centermatches desired layoutThe new flex column wrapper and direct
Skeletonusage preserve the list/skeleton behavior and look correct. One thing to double‑check:justify-centerwill vertically center the list items within the available height; if the previousListContaineraligned items from the top, you may prefer droppingjustify-center(or usingjustify-start) to avoid a subtle UX change.web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx (2)
13-42: Add error handling for CSV conversion.The
json2csvconversion could potentially throw an error if the data is malformed. Consider wrapping the conversion in a try-catch block to handle errors gracefully.useEffect(() => { if (!items || !ref.current) return; setIsPreparing(true); + + try { const flattenedItems = items.map((item) => { const row = { id: item.id, status: item.status, disputed: item.disputed, }; item.props.forEach((prop) => { row[`${prop.label} (${prop.description})`] = prop.value; }); return row; }); const csvData = json2csv(flattenedItems); const blob = new Blob([csvData], { type: "text/csv;charset=utf-8;" }); const link = ref.current; if (link.download !== undefined) { const url = URL.createObjectURL(blob); link.setAttribute("href", url); link.setAttribute("download", `Kleros-Curate-${registryAddress}.csv`); link.click(); } + } catch (error) { + console.error("Failed to generate CSV:", error); + // Optionally show user feedback + } finally { + setIsPreparing(false); + } - setIsPreparing(false); }, [items]);
37-42: Minor: Include registryAddress in dependency array.The
registryAddressprop is used within the effect (line 37) but is not included in the dependency array. While props are typically stable, for correctness and to satisfy ESLint's exhaustive-deps rule, consider adding it:- }, [items]); + }, [items, registryAddress]);web/src/components/ItemCard/index.tsx (3)
9-10: Consider usingcnconsistently instead of mixing withclsx.The
cnutility wrapsclsxwithtwMergefor better Tailwind class merging. Since you're already usingcnon lines 31 and 40, consider using it consistently instead ofclsxdirectly on line 50 to ensure proper class conflict resolution.Apply this diff:
-import { cn } from "~src/utils"; -import clsx from "clsx"; +import { cn } from "~src/utils";And on line 50:
- <Button - className={clsx( + <Button + className={cn(
12-14: Consider adding comments to explain the responsive calculation logic.The CSS calc formulas implement fluid sizing between 900px and 1250px breakpoints, but the intent isn't immediately clear. Adding brief comments would improve maintainability.
Example:
+// Fluid grid columns: scales from 1fr/150px/max-content to 1fr/180px/max-content between lg (900px) and xl (1250px) const landscapeGridColsCalc = "lg:grid-cols-[1fr_calc(150px+(180-150)*(min(max(100vw,900px),1250px)-900px)/(1250-900))_max-content]"; +// Fluid gap: scales from 16px to 36px between lg (900px) and xl (1250px) const landscapeGapCalc = "lg:gap-[calc(16px+(36-16)*(min(max(100vw,900px),1250px)-900px)/(1250-900))]";
37-37: Consider refactoring to use Tailwind consistently.Mixing inline styles with Tailwind classes creates an inconsistent styling approach. If
responsiveSize()is calculating dynamic column gaps, consider either incorporating it into thelandscapeGapCalcconstant or documenting why inline styles are necessary here.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
web/src/components/HistoryDisplay/index.tsx(7 hunks)web/src/components/ItemCard/index.tsx(2 hunks)web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx(2 hunks)web/src/pages/AllLists/RegistryDetails/List/index.tsx(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (3)
web/src/components/HistoryDisplay/index.tsx (4)
web/src/hooks/queries/useRequestsQuery.ts (1)
useItemRequests(48-64)web/src/hooks/useToggleThemeContext.tsx (1)
useTheme(18-20)web/src/components/StyledSkeleton.tsx (1)
HistorySkeletonCard(5-12)web/src/utils/date.ts (1)
formatDate(28-32)
web/src/components/ItemCard/index.tsx (2)
web/src/utils/index.ts (1)
cn(44-46)web/src/components/RegistryCard/StatusBanner.tsx (1)
mapFromSubgraphStatus(28-40)
web/src/pages/AllLists/RegistryDetails/List/index.tsx (1)
web/src/hooks/queries/useItemsQuery.ts (1)
ItemDetailsFragment(6-6)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (5)
web/src/components/HistoryDisplay/index.tsx (5)
19-19: LGTM! Type alias correctly defined.The
TimelineItemtype alias properly extracts the item type from theCustomTimelinecomponent'sitemsprop using TypeScript utility types.
23-24: LGTM! Theme detection properly implemented.The theme hook usage and light theme detection are correct. The boolean flag appropriately drives the color selection logic throughout the component.
26-34: Previous issue addressed—dependency array now complete.The
useMemodependency array now correctly includesisItem, ensuring items recompute when any dependency changes. This addresses the concern from the previous review.
36-46: LGTM! Rendering logic clean and correct.The component rendering handles all states appropriately—loading, empty, and populated. The Tailwind arbitrary variant syntax on line 42 correctly targets nested
.party-wrapperelements for responsive max-height control.
48-53: LGTM! Card wrapper properly structured.The
Cardcomponent is correctly used with appropriate Tailwind classes for layout and spacing. The structure cleanly wraps the header and timeline content.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
web/src/components/ItemCard/index.tsx (1)
49-57: Replace deep.button-textselector withtextClassNameon ButtonThe Button is still styled using the deep selector:
className={clsx( "bg-transparent p-0 flex-row-reverse gap-2", "[&_.button-text]:text-klerosUIComponentsPrimaryBlue [&_.button-text]:font-normal", "focus:bg-transparent hover:bg-transparent" )}This couples ItemCard to the internal
.button-textclass of@kleros/ui-components-libraryand is brittle against library changes. The v3 Button exposes atextClassNameprop for exactly this purpose.Prefer:
<Button className={cn( "bg-transparent p-0 flex-row-reverse gap-2", "focus:bg-transparent hover:bg-transparent" )} textClassName="text-klerosUIComponentsPrimaryBlue font-normal" text="Open" Icon={ArrowIcon} />This keeps the outer Button styling in
classNameand the text-specific styling intextClassName, without relying on internal selectors.
🧹 Nitpick comments (2)
web/src/components/ItemCard/index.tsx (2)
9-10: Prefercnconsistently instead of rawclsxwhere possibleYou already import
cn, which wrapsclsxandtwMerge. Using bothcnandclsxin the same file is a bit inconsistent and loses Tailwind class merging on the Button.You can simplify and standardize by routing the Button classes through
cnas well:-import { cn } from "~src/utils"; -import clsx from "clsx"; +import { cn } from "~src/utils"; ... - <Button - className={clsx( + <Button + className={cn( "bg-transparent p-0 flex-row-reverse gap-2", "[&_.button-text]:text-klerosUIComponentsPrimaryBlue [&_.button-text]:font-normal", "focus:bg-transparent hover:bg-transparent" )}
25-57: Consider avoiding nested interactive regions for better accessibilityRight now the
Cardis fully clickable viaonClick, and an innerButtonis rendered without its own handler:<Card ... onClick={() => navigateAndScrollTop(`/lists/item/${id?.toString()}`)}> ... <Button ... text="Open" Icon={ArrowIcon} /> </Card>This creates a nested interactive element pattern (a button inside a clickable container), which can be sub‑optimal for accessibility and keyboard/screen‑reader users.
Two possible improvements:
- Move navigation onto the Button and make the Card non-interactive; or
- Keep the Card clickable but render the right-hand control as non-interactive text/icon (or ensure the inner Button is aria-hidden / non-focusable).
Not urgent, but worth aligning with your broader accessibility goals during this Tailwind/UI‑library migration.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
web/src/components/ItemCard/index.tsx(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
🧬 Code graph analysis (1)
web/src/components/ItemCard/index.tsx (2)
web/src/utils/index.ts (1)
cn(44-46)web/src/components/RegistryCard/StatusBanner.tsx (1)
mapFromSubgraphStatus(28-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (3)
web/src/components/ItemCard/index.tsx (3)
12-15: Responsive calc helpers look correct and match LG breakpoint configurationThe
landscapeGridColsCalcandlandscapeGapCalcexpressions are well-formedcalc()formulas and use900pxas the lower clamp, which matches the overriddenlgbreakpoint (900px) configured for this app. This should give smooth interpolation between 900px and 1250px.Based on learnings
25-37: Card layout and grid template look valid; grid-rows syntax issue resolvedThe Card container and grid wrapper now:
- Use
flex grow w-full h-max lg:h-16on the Card, aligning with a fixed-height row on large screens.- Define
grid-rows-[repeat(3,min-content)]on mobile andlg:grid-rows-[1fr]on large screens, fixing the earlier invalidrepeat(3,)syntax.- Apply
columnGapviaresponsiveSize(12, 32, 900), which aligns with the 900px LG breakpoint configuration.No functional issues here; the previous
repeat(3,)bug is fully addressed.
39-47: Identifier fields mapping and responsive gap look goodThe left-hand content column:
- Uses a clear mobile (
flex-col) vs. desktop (lg:flex-row) layout and interpolatedlg:gap-[calc(...)]spacing, consistent with the calc helpers above.- Adds a
key={prop.label}toItemField, resolving the earlier missing-key issue for the mapped children.Assuming
labelis unique per item or per identifier prop, this is sufficient; otherwise you can fall back to a composite key (e.g.${prop.type}-${prop.label}) later if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
web/src/components/ActionButton/index.tsx (1)
49-56: Re: ButtonisDisabledprop — past concern still unresolved.The change from
disabledtoisDisabledwas flagged in a previous review, with a web search suggesting that v3 usesdisabled, notisDisabled. However, I was unable to find definitive documentation confirming the correct prop name for @kleros/ui-components-library v3.6.0.Some UI libraries like Chakra UI use
isDisabled, while others use standard HTMLdisabled. If the Kleros library is built on React Aria Components,isDisabledwould be correct. Otherwise, this may cause the button to not be disabled as expected.Please verify which prop the Button component from @kleros/ui-components-library v3.6.0 actually accepts. If it's
disabled, revert both occurrences (lines 50 and 65). If it'sisDisabled, the implementation is correct.Run this script to check the Button component's TypeScript definition:
#!/bin/bash # Check Button component props in node_modules if [ -f "node_modules/@kleros/ui-components-library/dist/index.d.ts" ]; then echo "=== Checking Button interface in type definitions ===" rg -A 20 "interface.*Button.*Props|type.*Button.*Props" node_modules/@kleros/ui-components-library/dist/ else echo "Type definition file not found" fi # Also check for Button export echo "" echo "=== Button exports ===" rg "export.*Button" node_modules/@kleros/ui-components-library/dist/web/src/global.css (1)
1-5: Critical: Reorder@import "tailwindcss"before other at-rules.Currently
@import "tailwindcss";on Line 4 comes after@tailwindand@source, which violates the CSS rule that all@importdirectives must appear before other at-rules (Biome is flagging this). This can lead to parse issues and broken Tailwind processing.Reorder the header like this so both imports come first:
-@import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css"; -@tailwind utilities; -@source "../../node_modules/@kleros/ui-components-library"; -@import "tailwindcss"; -@custom-variant dark (&:where(.dark, .dark *)); +@import "../../node_modules/@kleros/ui-components-library/dist/assets/theme.css"; +@import "tailwindcss"; +@source "../../node_modules/@kleros/ui-components-library"; +@tailwind utilities; +@custom-variant dark (&:where(.dark, .dark *));
🧹 Nitpick comments (6)
web/src/components/HistoryDisplay/Header.tsx (1)
6-11: Header Tailwind conversion looks good; consider marking the icon decorativeLayout and Tailwind classes are straightforward and match the intended header structure. For accessibility, you might want to mark the
HistoryIconas decorative so screen readers rely on the visible “History” text:- <HistoryIcon width={17} height={16} className="fill-klerosUIComponentsPrimaryText" /> + <HistoryIcon + width={17} + height={16} + className="fill-klerosUIComponentsPrimaryText" + aria-hidden="true" + />web/src/components/HistoryDisplay/index.tsx (2)
36-41: Prefer semantic element for empty state and consider simplifying Component memoTwo small points here:
labelis meant for form controls; for “No requests yet.” aporspanwould be more semantic and avoids suggesting a control association:- else if (items.length === 0) return <label className="self-center pb-8">No requests yet.</label>; + else if (items.length === 0) return <p className="self-center pb-8">No requests yet.</p>;
- The
ComponentuseMemo is fine as-is, but it could be inlined into JSX to reduce indirection if you want to simplify later.
58-117: Color constants repeated across cases – optional centralizationThe same hex colors (
#009aff,#6cc5ff,#9013fe,#b45fff,#f60c36,#ff5a78,#00c42b,#65dc7f) are repeated across multiple item variants. This is fine functionally, but if these map to named theme tokens, it may be worth extracting a small helper (e.g.,getVariantColor(isLightTheme, "primary" | "warning" | ...)) or constants to keep things DRY and make future palette changes safer.web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
25-32: Consider using Tailwind utilities for all spacing.The component mixes inline styles (
paddingInline,gapvia style prop) with Tailwind classes. WhileresponsiveSize()provides dynamic sizing, this creates an inconsistent styling approach within a Tailwind migration.If
responsiveSize()returns static breakpoint-based values, consider replacing inline styles with Tailwind responsive utilities:- <div - className="flex flex-col justify-center w-full py-6 mt-4 bg-klerosUIComponentsMediumBlue leading-6 lg:flex-row lg:justify-between" - style={{ paddingInline: responsiveSize(24, 32) }} - > + <div className="flex flex-col justify-center w-full px-6 py-6 mt-4 bg-klerosUIComponentsMediumBlue leading-6 lg:flex-row lg:justify-between lg:px-8">Similarly for line 32:
- <div className="flex flex-wrap" style={{ gap: responsiveSize(16, 24) }}> + <div className="flex flex-wrap gap-4 lg:gap-6">If
responsiveSize()provides non-standard breakpoint values that don't map to Tailwind's spacing scale, the current approach is acceptable.web/src/components/InformationCards/RegistryInformationCard/index.tsx (1)
69-73: Consider Tailwind utilities for consistent spacing.Similar to the Policies component, this mixes inline styles (
marginBlock,marginInline) with Tailwind classes. WhileresponsiveSize()provides dynamic values, consider whether standard Tailwind responsive utilities could replace these:- <hr - className="border-none h-px bg-klerosUIComponentsStroke" - style={{ marginBlock: responsiveSize(20, 28), marginInline: responsiveSize(24, 32) }} - /> + <hr className="border-none h-px bg-klerosUIComponentsStroke my-5 mx-6 lg:my-7 lg:mx-8" />And for line 73:
- <div className="flex flex-wrap justify-between gap-5 pb-3" style={{ paddingInline: responsiveSize(24, 32) }}> + <div className="flex flex-wrap justify-between gap-5 pb-3 px-6 lg:px-8">If
responsiveSize()returns values that don't align with Tailwind's spacing scale, the inline style approach is reasonable.web/src/components/StatsAndFilters/Filters.tsx (1)
47-63: Optional cleanup: remove redundantisDesktopguard and DRY icon classes.Inside the list view toggle, the
if (isDesktop)check in theListIcononClick is redundant because this entire block only renders whenisDesktop && isListFilteris true, and the icon class strings are duplicated.You could simplify and de-duplicate like this:
- {isListView ? ( - <GridIcon - className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100" - onClick={() => setIsListView(false)} - /> - ) : ( - <ListIcon - className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100" - onClick={() => { - if (isDesktop) { - setIsListView(true); - } - }} - /> - )} + {isListView ? ( + <GridIcon + className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100" + onClick={() => setIsListView(false)} + /> + ) : ( + <ListIcon + className="w-4 h-4 overflow-hidden cursor-pointer fill-klerosUIComponentsPrimaryBlue hover:fill-klerosUIComponentsSecondaryBlue transition duration-100" + onClick={() => setIsListView(true)} + /> + )}(Optionally, pull the shared class string into a small
const iconClassName = "..."to avoid repeating it.)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
web/src/components/ActionButton/index.tsx(2 hunks)web/src/components/HistoryDisplay/Header.tsx(1 hunks)web/src/components/HistoryDisplay/Party/index.tsx(1 hunks)web/src/components/HistoryDisplay/index.tsx(7 hunks)web/src/components/InformationCards/RegistryInformationCard/Policies.tsx(2 hunks)web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx(2 hunks)web/src/components/InformationCards/RegistryInformationCard/index.tsx(4 hunks)web/src/components/InformationCards/StatusDisplay.tsx(2 hunks)web/src/components/StatsAndFilters/Filters.tsx(1 hunks)web/src/global.css(1 hunks)web/src/layout/Header/navbar/Menu/Help.tsx(2 hunks)web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- web/src/pages/AllLists/RegistryDetails/ItemsDownloadLabel.tsx
- web/src/components/InformationCards/StatusDisplay.tsx
- web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx
- web/src/components/HistoryDisplay/Party/index.tsx
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Applied to files:
web/src/layout/Header/navbar/Menu/Help.tsxweb/src/global.css
📚 Learning: 2025-10-24T21:25:59.174Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
Applied to files:
web/src/global.css
📚 Learning: 2025-11-06T23:06:51.514Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/global.css:3-3
Timestamp: 2025-11-06T23:06:51.514Z
Learning: In Tailwind v4, you can use `import "tailwindcss" source("path")` syntax to control automatic content detection by passing the source() argument directly on the import statement. This is in addition to the standalone `source "path"` directive. Both syntaxes are valid: `import "tailwindcss" source("../../node_modules/kleros/ui-components-library");` and `source "../../node_modules/kleros/ui-components-library";`
Applied to files:
web/src/global.css
📚 Learning: 2025-10-31T19:54:12.499Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/Header/DesktopHeader.tsx:43-44
Timestamp: 2025-10-31T19:54:12.499Z
Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).
Applied to files:
web/src/global.css
📚 Learning: 2025-10-31T20:37:01.310Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/components/OverlayPortal.tsx:5-8
Timestamp: 2025-10-31T20:37:01.310Z
Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4.
```
<!-- [remove_learning]
dcbe3a95-44f6-47d5-806e-64b74d549e4b
Applied to files:
web/src/global.css
🧬 Code graph analysis (3)
web/src/components/InformationCards/RegistryInformationCard/index.tsx (2)
web/src/utils/index.ts (1)
cn(44-46)web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
Policies(21-59)
web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
web/src/utils/getIpfsUrl.ts (1)
getIpfsUrl(4-8)
web/src/components/HistoryDisplay/index.tsx (4)
web/src/hooks/queries/useRequestsQuery.ts (1)
useItemRequests(48-64)web/src/hooks/useToggleThemeContext.tsx (1)
useTheme(18-20)web/src/components/StyledSkeleton.tsx (1)
HistorySkeletonCard(5-12)web/src/utils/date.ts (1)
formatDate(28-32)
🪛 Biome (2.1.2)
web/src/global.css
[error] 4-4: This @import is in the wrong position.
Any @import rules must precede all other valid at-rules and style rules in a stylesheet (ignoring @charset and @layer), or else the @import rule is invalid.
Consider moving import position.
(lint/correctness/noInvalidPositionAtImportRule)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (8)
web/src/layout/Header/navbar/Menu/Help.tsx (1)
49-57: Fix invalid z-index utility.Line 52 uses
z-1, which is not a valid Tailwind utility. Tailwind's default z-index scale includes 0, 10, 20, 30, 40, 50, and auto, but not 1.Apply this diff to use arbitrary value syntax:
- "flex flex-col absolute max-h-[80vh] overflow-y-auto w-[86vw] max-w-[444px] top-[5%] left-1/2 transform -translate-x-1/2 z-1 p-3 pb-6", + "flex flex-col absolute max-h-[80vh] overflow-y-auto w-[86vw] max-w-[444px] top-[5%] left-1/2 transform -translate-x-1/2 z-[1] p-3 pb-6",⛔ Skipped due to learnings
Learnt from: kyrers Repo: kleros/curate-v2 PR: 89 File: web/src/components/OverlayPortal.tsx:5-8 Timestamp: 2025-10-31T20:37:01.310Z Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4. ``` <!-- [remove_learning] dcbe3a95-44f6-47d5-806e-64b74d549e4bweb/src/components/HistoryDisplay/index.tsx (3)
1-20: Type aliasing TimelineItem off CustomTimeline props is a solid choiceDeriving
TimelineItemfromReact.ComponentProps<typeof CustomTimeline>["items"][number]keeps this file aligned with the library’s item shape and avoids drift when the component API changes. Imports forCard,CustomTimeline,clsx, anduseThemealso look consistent with the Tailwind-and-theme migration goals.
21-35: items useMemo wiring and dependencies look correct
itemsis recomputed only whendata,isLightTheme, orisItemchange, which matches the arguments passed intoconstructItemsFromRequest. The guardif (!items || isLoading)later safely handles theundefinedcase fromdata?.requests. This addresses the earlier dependency issue aroundisItem.
43-48: Card wrapper Tailwind layout matches intentWrapping the history content in a
Cardwithflex flex-col w-full h-auto items-start gap-14 py-6 px-8gives a clear, responsive container and aligns with the Tailwind-based layout approach elsewhere. No issues spotted here.web/src/components/InformationCards/RegistryInformationCard/index.tsx (2)
51-51: Good use of the cn utility for class composition.The
cnutility properly merges the base classes with the optionalclassNameprop, enabling external styling customization while maintaining type safety.
76-79: Arbitrary Tailwind variants in tooltipProps are supported.The Copiable component in @kleros/ui-components-library v3 passes tooltipProps.className through to the tooltip, supporting arbitrary Tailwind utility classes and variants. The code at lines 76–79 using
[&_small]:text-smis correct.One consideration: ensure your Tailwind build includes the library package as a source so these arbitrary classes are picked up during the build process.
web/src/components/InformationCards/RegistryInformationCard/Policies.tsx (1)
13-14: Based on my verification, I can now provide the rewritten review comment:The hover state syntax is valid and the custom color is properly available.
The
hover:[&_svg]:fill-klerosUIComponentsSecondaryBluesyntax is correctly using Tailwind v4's arbitrary variants with descendant selectors. The custom colorklerosUIComponentsSecondaryBlueis sourced from the kleros/ui-components-library via the@sourcedirective in global.css, which scans and makes external CSS variables available to Tailwind. This same color is already successfully used in Filters.tsx with identical syntax, confirming it works as intended.web/src/components/StatsAndFilters/Filters.tsx (1)
34-45: Filters.tsx DropdownSelect v3 usage confirmed correct; flag separate migration issue in ChainInput.tsx.The v3 API pattern you're verifying is confirmed across the codebase:
- Search.tsx uses identical
{ id, itemValue, text }item shape +callback((item) => item.itemValue)- Filters.tsx correctly mirrors this pattern with
defaultSelectedKey={order}pointing to itemidCritical finding: ChainInput.tsx (
web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx) is using an incompatible older API—{ text, value }items withcallbackreceiving raw values instead of item objects. This file likely has a runtime bug or needs immediate migration to the v3 pattern to match the rest of the codebase.For Filters.tsx specifically: the implementation is correct and consistent with the library's v3.6.0 API as deployed elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/src/components/HistoryDisplay/index.tsx (1)
98-105: UsechallengeTimefor “Removal Challenged” subtitle for consistencyIn the registration branch, the “Challenged” event subtitle uses
request.challengeTime, but in the clearing branch it usesrequest.submissionTime, which likely shows the wrong timestamp for the challenge event.Consider aligning it with the registration case:
- subtitle: formatDate(request.submissionTime), + subtitle: formatDate(request.challengeTime),This keeps the “Removal Challenged” entry anchored to when the challenge actually occurred.
♻️ Duplicate comments (1)
web/src/layout/Header/navbar/Menu/Help.tsx (1)
70-70: Fix invalid Tailwind line-height utility.Line 70 uses
leading-18px, which is invalid Tailwind syntax. Arbitrary line-height values must use square brackets:leading-[18px].This issue was previously flagged and marked as addressed, but the invalid syntax is still present in the current code.
Apply this diff:
- <small className="text-base leading-18px font-normal transition-colors duration-100 group-hover:text-klerosUIComponentsSecondaryPurple"> + <small className="text-base leading-[18px] font-normal transition-colors duration-100 group-hover:text-klerosUIComponentsSecondaryPurple"> {item.text} </small>
🧹 Nitpick comments (2)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (1)
14-14: Responsive gap calculation matches LG breakpoint; consider documenting intentThe
landscapeColumnGapCalcclass correctly interpolates horizontal gap from 24px → 32px between 900px and 1250px viewport widths, aligning with the overriddenlgbreakpoint at 900px. A short comment explaining this formula would help future maintainability.Based on learnings
web/src/components/HistoryDisplay/index.tsx (1)
26-41: SimplifyCustomTimelineclassName;clsxis unnecessary here
classNameis a static string with no conditional pieces, soclsxdoesn’t add value and the extra import can be dropped.-import clsx from "clsx"; @@ - return <CustomTimeline className={clsx("w-full mb-8", "[&_h2]:m-0 [&_div]:max-h-none")} {...{ items }} />; + return ( + <CustomTimeline + className="w-full mb-8 [&_h2]:m-0 [&_div]:max-h-none" + {...{ items }} + /> + );The
itemscomputation and loading/empty states otherwise look fine.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
web/src/components/HistoryDisplay/index.tsx(7 hunks)web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx(2 hunks)web/src/components/InformationCards/RegistryInformationCard/index.tsx(4 hunks)web/src/layout/Header/navbar/Menu/Help.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- web/src/components/InformationCards/RegistryInformationCard/index.tsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Applied to files:
web/src/layout/Header/navbar/Menu/Help.tsx
🧬 Code graph analysis (2)
web/src/components/HistoryDisplay/index.tsx (4)
web/src/hooks/queries/useRequestsQuery.ts (1)
useItemRequests(48-64)web/src/hooks/useToggleThemeContext.tsx (1)
useTheme(18-20)web/src/components/StyledSkeleton.tsx (1)
HistorySkeletonCard(5-12)web/src/utils/date.ts (1)
formatDate(28-32)
web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (4)
web/src/utils/index.ts (2)
isUndefined(5-5)cn(44-46)web/src/utils/getIpfsUrl.ts (1)
getIpfsUrl(4-8)web/src/consts/index.ts (1)
DEFAULT_LIST_LOGO(23-23)web/src/consts/chains.ts (1)
SUPPORTED_CHAINS(9-11)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: CodeQL
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (7)
web/src/layout/Header/navbar/Menu/Help.tsx (1)
52-54: Fix undefined z-index utilityz-1.Line 52 uses
z-1, which is not a valid Tailwind utility. Tailwind v4 provides z-0, z-10, z-20, z-30, z-40, and z-50 by default. Replacez-1with an appropriate z-index value (likelyz-10).The
shadow-customutility is correctly defined via the--shadow-customCSS variable inglobal.cssand will work as expected in Tailwind v4.⛔ Skipped due to learnings
Learnt from: kyrers Repo: kleros/curate-v2 PR: 89 File: web/src/components/OverlayPortal.tsx:5-8 Timestamp: 2025-10-31T20:37:01.310Z Learning: In Tailwind CSS v4, the `z-<number>` syntax directly sets `z-index: <number>;` for any numeric value (e.g., `z-9999` results in `z-index: 9999;`). Arbitrary value brackets `z-[<value>]` are not required for numeric z-index values in v4. ``` <!-- [remove_learning] dcbe3a95-44f6-47d5-806e-64b74d549e4bLearnt from: kyrers Repo: kleros/curate-v2 PR: 89 File: web/src/layout/Header/DesktopHeader.tsx:43-44 Timestamp: 2025-10-31T19:54:12.499Z Learning: In Tailwind CSS v4, the important modifier uses a trailing `!` after the utility class (e.g., `fill-white!`), unlike v3 which used a leading `!` prefix (e.g., `!fill-white`). This applies to all utilities including arbitrary values and after variants (e.g., `sm:hover:bg-green-500!`).Learnt from: kyrers Repo: kleros/curate-v2 PR: 89 File: web/src/styles/breakpoints.ts:1-1 Timestamp: 2025-11-14T22:12:39.974Z Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.web/src/components/InformationCards/RegistryInformationCard/TopInfo.tsx (3)
8-11: Utility imports are appropriate and fully used
cnandisUndefinedare both used below (layout classes and skeleton conditions), so the shared utils import is correct with no dead code.
36-63: Top-level layout and logo/title/description skeletons look correctThe flex layout, responsive padding via
responsiveSize,isUndefined-based skeleton rendering forlogoURI,title, anddescription, plus the IPFS logo fallback on image error all look consistent and robust for loading states and broken logos.
64-94: Right column layout,cnusage, and Copiable/link styling are solidThe
cn-composed flex container with responsive gap/shrink behavior,Copiableconfiguration (includingtooltipProps), and the styled anchor (primary blue, hover underline, external link attributes) preserve expected behavior while matching the Tailwind migration.web/src/components/HistoryDisplay/index.tsx (3)
1-24: Type-safe wiring between theme, CustomTimeline, and item shape looks solidImports of
Card/CustomTimeline,useTheme, and theTimelineItemalias derived fromCustomTimeline’sitemsprop, plus theisLightThemeboolean, all line up correctly with later usage; no issues spotted here.
44-48: Card wrapper Tailwind layout looks appropriateUsing a flex column
Cardwith full width, auto height, padding, and gap is a reasonable migration from styled-components here; structure and composition withHeaderand the timeline content read cleanly.
51-57: constructItemsFromRequest typing and visual semantics are consistentUpdating
constructItemsFromRequestto returnTimelineItem[]with a locally typedhistoryItemsarray now matches the reducer usage (acc.push(...history)). The color variants and icons for registration vs. clearing (included vs. rejected/removed) are coherent and align with the intended positive/negative states.Also applies to: 61-62, 69-71, 77-88, 90-97, 101-102, 108-116, 120-121
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
♻️ Duplicate comments (1)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)
9-10: Duplicate: See FileInput.tsx comment.The typo and code duplication issues here are identical to those in
FileInput.tsxlines 9-10. Refer to that comment for the suggested fix.
🧹 Nitpick comments (10)
web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx (1)
8-20: DropdownSelect migration looks correct; consider small cleanup and verifydefaultValuesemanticsThe new
itemsshape ({ id, text, itemValue }) andcallback={(item) => handleChange(item.itemValue)}look consistent with the updatedDropdownSelectAPI and correctly keephandleWritereceiving the chainId as a string.As a minor tidy-up,
handleChangeis now only ever called with a number, so you could either narrow its signature tonumberor inline it in the callback to reduce indirection, for example:- const handleChange = (value: string | number) => { - handleWrite(value.toString()); - }; return ( <DropdownSelect items={[ { id: mainnet.id, text: getChainName(mainnet.id), itemValue: mainnet.id }, { id: arbitrum.id, text: getChainName(arbitrum.id), itemValue: arbitrum.id }, { id: gnosis.id, text: getChainName(gnosis.id), itemValue: gnosis.id }, { id: polygon.id, text: getChainName(polygon.id), itemValue: polygon.id }, ]} - callback={(item) => handleChange(item.itemValue)} + callback={(item) => handleWrite(item.itemValue.toString())} defaultValue={Number(fieldProp.value ?? mainnet.id)} /> );Also, since the
DropdownSelectitems API changed, please double-check the v3 docs to confirm thatdefaultValueshould still be the numeric value you’re passing (Number(fieldProp.value ?? mainnet.id)) and not, for example, theidfield; otherwise the initial selected chain might not match expectations.web/src/pages/SubmitItem/Policy/ReadPolicy.tsx (1)
10-14: Tailwind migration is fine; consider hardening the URL construction.The switch from a styled-component to a
Linkwith Tailwind classes looks correct and keeps behavior intact. To make the query parameter handling more robust (and future‑proof ifpolicyURIever contains&or other reserved characters), consider encoding the URL value:- return ( - <Link className="self-center text-xl mb-8" to={`/attachment/?url=${getIpfsUrl(policyURI ?? "")}`}> + return ( + <Link + className="self-center text-xl mb-8" + to={`/attachment/?url=${encodeURIComponent(getIpfsUrl(policyURI ?? ""))}`} + > → Read the policy here ← </Link> );Optionally, you could also skip rendering the link when there is no
policyURIavailable (e.g., earlyreturn null), to avoid navigating to/attachment/?url=with an empty value.web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1)
16-16: Consider refactoring inline style to Tailwind utilities.Using an inline
styleattribute withresponsiveSize()undermines the Tailwind migration. Consider refactoring this to use Tailwind's responsive spacing utilities or CSS custom properties defined in@theme.For example, if
responsiveSize(68, 40)represents responsive margin-bottom values, you could use Tailwind classes:- style={{ marginBottom: responsiveSize(68, 40) }} + className={cn("w-[80vw] mb-10 lg:mb-17", landscapeWitdhCalc)} - className={cn("w-[80vw]", landscapeWitdhCalc)}Or define a CSS variable in
@themeand use it:@theme { --spacing-responsive-bottom: 40px; @media (min-width: 900px) { --spacing-responsive-bottom: 68px; } }- style={{ marginBottom: responsiveSize(68, 40) }} + className={cn("w-[80vw] mb-(--spacing-responsive-bottom)", landscapeWitdhCalc)} - className={cn("w-[80vw]", landscapeWitdhCalc)}web/src/pages/SubmitItem/Header/index.tsx (1)
46-46: Consider completing the Tailwind migration.The code mixes Tailwind classes with inline styles using
responsiveSize. While acceptable during migration, consider replacing the inline styles with Tailwind's responsive utilities for consistency.For example,
paddingInline: responsiveSize(24, 32)could be replaced with:- style={{ marginBottom: responsiveSize(36, 36), paddingInline: responsiveSize(24, 32) }} + className={clsx("flex flex-wrap justify-between gap-6", "h-auto w-[80vw] lg:w-[91vw]", "mt-[60px] py-6 mb-9 px-6 lg:px-8")}web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx (1)
7-7: Extract duplicated constant to a shared utility.The
landscapeWitdhCalc(or corrected:landscapeWidthCalc) constant is duplicated across TextInput.tsx (line 7), AddressInput.tsx (line 8), and LinkInput.tsx (line 7). This violates the DRY principle.Consider extracting this to a shared constants file, for example
web/src/styles/constants.ts:export const LANDSCAPE_WIDTH_CALC = "lg:w-[calc(200px+(720-200)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";Then import and use it in all three files:
import { LANDSCAPE_WIDTH_CALC } from "~src/styles/constants"; // Usage: className={cn("w-[80vw]", LANDSCAPE_WIDTH_CALC)}web/src/pages/SubmitItem/Preview/index.tsx (1)
10-10: Consider removing redundantpy-0utility.The
py-0class is redundant when no vertical padding is needed (which is the default). You can safely remove it for cleaner code.- <div className="flex flex-col items-center w-full py-0" style={{ paddingInline: responsiveSize(10, 130) }}> + <div className="flex flex-col items-center w-full" style={{ paddingInline: responsiveSize(10, 130) }}>web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (1)
7-7: Consider extracting the responsive width calculation to a shared utility.The
landscapeWitdhCalc(once the typo is fixed) contains a complex responsive width calculation that appears to be duplicated across multipleFieldInputcomponents per the AI summary. Consider extracting this to a shared constant or utility function to improve maintainability and ensure consistency.For example, in
web/src/styles/responsiveSize.tsor a newweb/src/styles/responsiveWidth.ts:export const LANDSCAPE_WIDTH_CALC = "lg:w-[calc(200px+(720-200)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";Then import and use across all FieldInput components:
+import { LANDSCAPE_WIDTH_CALC } from "styles/responsiveWidth"; -const landscapeWitdhCalc = "lg:w-[calc(200px+(720-200)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";web/src/pages/SubmitItem/index.tsx (2)
14-14: Consider usingcnutility instead ofclsxfor consistency.Other migrated files use the
cnutility (which combinesclsxandtailwind-merge) for className composition. Usingcnhere would ensure Tailwind class conflicts are properly resolved and maintain consistency with the rest of the codebase.-import clsx from "clsx"; +import { cn } from "~src/utils";<div - className={clsx("flex flex-col w-full max-w-landscape", "bg-klerosUIComponentsLightBackground my-0 mx-auto")} + className={cn("flex flex-col w-full max-w-landscape", "bg-klerosUIComponentsLightBackground my-0 mx-auto")} style={{ paddingInline: responsiveSize(24, 32), paddingTop: responsiveSize(24, 28), paddingBottom: responsiveSize(76, 96), }} >Also applies to: 38-45
59-63: LGTM with minor suggestion.The not-connected state UI is clear and functional. The migration to Tailwind classes is correctly applied.
For improved semantics, consider wrapping the content in a more semantic element:
- <div className="flex flex-col items-center text-center text-klerosUIComponentsPrimaryText"> + <section className="flex flex-col items-center text-center text-klerosUIComponentsPrimaryText" aria-labelledby="connect-prompt"> + <h2 id="connect-prompt" className="sr-only">Connect Wallet Required</h2> To submit a new item, connect first <hr /> <ConnectWallet /> - </div> + </section>web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx (1)
5-7: Consider removing the empty interface.The
IConfirmationBoxinterface is empty and the component takes no props. You can simplify by removing the interface and type annotation entirely.Apply this diff to simplify:
-interface IConfirmationBox {} - -const ConfirmationBox: React.FC<IConfirmationBox> = ({}) => { +const ConfirmationBox: React.FC = () => {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (26)
web/src/pages/SubmitItem/Header/index.tsx(2 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/BooleanInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx(2 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx(2 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/StyledField.tsx(0 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/index.tsx(1 hunks)web/src/pages/SubmitItem/NavigationButtons/NextButton.tsx(1 hunks)web/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsx(1 hunks)web/src/pages/SubmitItem/NavigationButtons/SubmitItemButton.tsx(1 hunks)web/src/pages/SubmitItem/NavigationButtons/index.tsx(1 hunks)web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx(1 hunks)web/src/pages/SubmitItem/Policy/Info.tsx(2 hunks)web/src/pages/SubmitItem/Policy/ReadPolicy.tsx(1 hunks)web/src/pages/SubmitItem/Policy/index.tsx(2 hunks)web/src/pages/SubmitItem/Preview/ItemDisplay.tsx(1 hunks)web/src/pages/SubmitItem/Preview/ListDisplay.tsx(2 hunks)web/src/pages/SubmitItem/Preview/index.tsx(1 hunks)web/src/pages/SubmitItem/Timeline.tsx(1 hunks)web/src/pages/SubmitItem/Title.tsx(1 hunks)web/src/pages/SubmitItem/index.tsx(2 hunks)
💤 Files with no reviewable changes (1)
- web/src/pages/SubmitItem/ItemField/FieldInput/StyledField.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:42:03.737Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/components/ActionButton/Modal/EvidenceUpload.tsx:74-82
Timestamp: 2024-11-04T13:42:03.737Z
Learning: In `web/src/components/ActionButton/Modal/EvidenceUpload.tsx`, the `uploadFile` function already manages error handling and logging, so additional error handling after calling it is unnecessary.
Applied to files:
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsxweb/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx
📚 Learning: 2024-11-04T13:41:01.846Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx:67-80
Timestamp: 2024-11-04T13:41:01.846Z
Learning: In React components, when a button is used within a form, calling `e.preventDefault()` in the event handler is necessary to prevent the default form submission, even when using an `onClick` handler.
Applied to files:
web/src/pages/SubmitItem/NavigationButtons/SubmitItemButton.tsxweb/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsxweb/src/pages/SubmitItem/ItemField/index.tsxweb/src/pages/SubmitItem/NavigationButtons/NextButton.tsx
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.
Applied to files:
web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.
Applied to files:
web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx
🧬 Code graph analysis (12)
web/src/pages/SubmitItem/ItemField/FieldInput/ChainInput.tsx (1)
web/src/components/ChainIcon.tsx (1)
getChainName(27-44)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)
web/src/utils/index.ts (1)
cn(44-46)
web/src/pages/SubmitItem/Header/index.tsx (1)
web/src/utils/format.ts (2)
formatValue(11-15)formatUnitsWei(9-9)
web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)
web/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsx (1)
web/src/utils/index.ts (1)
isEmpty(13-13)
web/src/pages/SubmitItem/Policy/Info.tsx (1)
web/src/utils/index.ts (1)
cn(44-46)
web/src/pages/SubmitItem/Policy/ReadPolicy.tsx (1)
web/src/utils/getIpfsUrl.ts (1)
getIpfsUrl(4-8)
web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx (1)
web/src/utils/index.ts (1)
cn(44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)
web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (2)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (20)
web/src/pages/SubmitItem/ItemField/FieldInput/BooleanInput.tsx (1)
10-10: Switch prop migration toisSelectedappears correctThe controlled boolean logic is preserved and the new
isSelected={valueAsBool}prop should align with the updatedSwitchAPI, assuming v3.6.0 indeed expectsisSelectedinstead ofchecked. Please double-check the@kleros/ui-components-librarydocs to confirm the prop name andonChangesignature match this usage.web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1)
10-12: LGTM!The change from handling DOM events to handling numeric values aligns correctly with the NumberField API from @kleros/ui-components-library v3.
web/src/pages/SubmitItem/Policy/index.tsx (1)
13-22: LGTM!Clean migration from styled-components to Tailwind classes. The
flex flex-collayout preserves the original container behavior.web/src/pages/SubmitItem/NavigationButtons/SubmitItemButton.tsx (1)
54-74: LGTM!Correct migration of the Button API from
disabledtoisDisabled, consistent with @kleros/ui-components-library v3. The button logic and submission flow remain intact.web/src/pages/SubmitItem/NavigationButtons/NextButton.tsx (1)
42-42: LGTM!Correct update of the Button prop from
disabledtoisDisabledfor compatibility with @kleros/ui-components-library v3.web/src/pages/SubmitItem/Title.tsx (1)
8-8: LGTM!Clean migration to Tailwind with proper semantic HTML. The responsive width classes correctly apply mobile-first styling.
web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx (1)
31-42: Good use of thecnutility for className composition.The migration from styled-components to Tailwind classes is well-executed. The use of the
cnutility allows for clean composition of multiple class strings, and the child selector syntax[&_small]:whitespace-pre-linecorrectly targets nested elements.web/src/pages/SubmitItem/Policy/Info.tsx (1)
14-16: LGTM!Clean migration to Tailwind classes with proper use of the
cnutility for className composition.web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)
33-44: LGTM!Consistent migration pattern with FileInput.tsx. The className composition and upload flow are correctly implemented.
web/src/pages/SubmitItem/Header/index.tsx (1)
43-69: Well-structured refactor from styled-components.The migration to a Card-based layout with Tailwind classes is clean and maintainable. The custom color classes (
text-klerosUIComponentsPrimaryText,text-klerosUIComponentsSecondaryPurple) correctly use the theme tokens from the UI library, and the responsive layout logic is preserved.web/src/pages/SubmitItem/Preview/ListDisplay.tsx (1)
22-32: LGTM! Clean migration to Tailwind classes.The styled-components have been successfully replaced with Tailwind utility classes. The inline
gapstyle usingresponsiveSizeis retained for responsive behavior.web/src/pages/SubmitItem/Timeline.tsx (1)
33-33: LGTM! Responsive behavior correctly migrated to Tailwind.The styled-components wrapper has been successfully replaced with Tailwind utility classes. The timeline is hidden by default and becomes visible with absolute positioning on large screens (≥900px as per learnings).
web/src/pages/SubmitItem/NavigationButtons/PreviousButton.tsx (1)
14-19: LGTM! Conditional visibility correctly implemented.The styled-components wrapper has been replaced with a
classNameprop that conditionally applieshiddenorflexbased on whetherprevRouteis empty. This maintains the same behavior while using Tailwind utilities.web/src/pages/SubmitItem/ItemField/index.tsx (1)
31-44: LGTM! Clean migration to className-based styling.The styled-components container has been successfully replaced with a plain
divusing Tailwind classes. The Skeleton components now useclassNamefor bottom margin spacing, maintaining the same visual layout.web/src/pages/SubmitItem/NavigationButtons/index.tsx (1)
13-16: LGTM! Flex layout correctly migrated.The styled Container has been replaced with a
divusing Tailwind flex utilities (flex flex-wrap justify-center gap-6). The responsive margin is preserved via inline style.web/src/pages/SubmitItem/Preview/index.tsx (1)
22-22: Verify the purpose of this empty overlay div.This absolutely positioned div appears to be a leftover from the
Overlaystyled component mentioned in the migration. Without background color, opacity, z-index, or pointer-events, it has no visual or interactive effect. Please verify whether this element is still needed or should be removed.If this overlay is intentional, apply the necessary styling:
- <div className="absolute w-full h-full" /> + <div className="absolute inset-0 bg-black/50 z-10" /> {/* Example overlay styling */}Or remove it if no longer needed:
- <div className="absolute w-full h-full" />web/src/pages/SubmitItem/Preview/ItemDisplay.tsx (1)
22-25: LGTM!Clean migration from styled-components to Tailwind utility classes. The responsive sizing and custom color classes are correctly applied.
web/src/pages/SubmitItem/index.tsx (1)
47-47: The className prop is accepted, but only applied to the Button element when unverified.The EnsureAuth component does accept and destructure the
classNameprop correctly. However, the className is only forwarded to the internalButtoncomponent and is not applied when rendering children (in the verified state). This meansclassName="self-center"only affects the styling of the "Sign In" button, not the overall EnsureAuth wrapper or verified content. Consider whether the className should also wrap the children or if this conditional behavior is intentional.web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx (2)
11-18: LGTM! Clean migration to Tailwind.The replacement of the styled
Containercomponent with a plaindivand Tailwind utility classmb-8follows the PR's migration strategy correctly.
14-14: VerifyisSelectedprop compatibility by checking library source or running imports.The PR follows a consistent naming pattern (e.g.,
disabled→isDisabledfor Button), andisSelectedaligns with modern React UI library conventions. However, web searches did not return the specific@kleros/ui-components-libraryv3 Checkbox API documentation. To confirm the prop name:
- Check the library's
Checkboxcomponent export innode_modules/@kleros/ui-components-libraryor its GitHub source- Run
npm list @kleros/ui-components-libraryto verify v3 is installed- Review the type definitions (
.d.ts) for the Checkbox component props interface
web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (1)
11-17: Fix validation logic to allow user input.The validation still blocks all user input when the URL is invalid. Users cannot type partial URLs because
handleWriteis only called for complete, valid URLs, and the error state is never cleared.Apply this diff to allow typing while providing validation feedback:
const handleChange = (value: string) => { - if (!isValidUrl(value)) { - setIsError(true); - return; - } - handleWrite(value); + const isValid = value === "" || isValidUrl(value); + setIsError(!isValid && value !== ""); + handleWrite(value); };This allows users to type freely, shows an error for non-empty invalid URLs, and lets form-level validation prevent submission.
web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (1)
16-16: Fix NaN handling with nullish coalescing operator.
Number(fieldProp.value) ?? 0does not handleNaNcorrectly. WhenfieldProp.valueis undefined or an invalid numeric string,Number(fieldProp.value)returnsNaN, andNaN ?? 0evaluates toNaN(not0) because the nullish coalescing operator only checks fornullorundefined, notNaN.Apply this diff:
- value={Number(fieldProp.value) ?? 0} + value={Number(fieldProp.value) || 0}Or for more explicit handling:
- value={Number(fieldProp.value) ?? 0} + value={fieldProp.value ? Number(fieldProp.value) : 0}
🧹 Nitpick comments (1)
web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)
1-1: Consider using CSS custom properties or Tailwind's built-in responsive utilities.The calc expression is mathematically correct but quite complex and difficult to maintain. Consider these alternatives:
- Define CSS custom properties in your theme for these fluid calculations
- Use Tailwind's
clamp()plugin or custom spacing scale- Document the formula's purpose (e.g., "Scales input width from 200px to 720px between mobile and desktop")
Example with CSS custom properties:
:root { --field-width-fluid: clamp(200px, 200px + (720 - 200) * ((100vw - 375px) / (1250 - 375)), 720px); }Then use:
lg:w-[var(--field-width-fluid)]
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx(2 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx(2 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx(1 hunks)web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts(1 hunks)web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- web/src/pages/SubmitItem/ItemField/FieldInput/FileInput.tsx
- web/src/pages/SubmitItem/Policy/ConfirmationBox.tsx
- web/src/pages/SubmitItem/ItemField/FieldInput/TextInput.tsx
- web/src/pages/SubmitItem/ItemField/FieldInput/AddressInput.tsx
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:34:45.425Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/confirmEmail.ts:24-36
Timestamp: 2024-11-04T13:34:45.425Z
Learning: In the `confirmEmail` function in `web/src/utils/atlas/confirmEmail.ts`, input validation for the address is performed in the calling component, and additional checks are done in the API call itself. Input validation does not need to be repeated in this function.
Applied to files:
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx
📚 Learning: 2024-11-04T13:39:19.748Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/utils/atlas/updateEmail.ts:21-38
Timestamp: 2024-11-04T13:39:19.748Z
Learning: For the `updateEmail` function in `web/src/utils/atlas/updateEmail.ts`, input validation and error handling are performed in the component that utilizes it. Therefore, additional checks within this utility function are unnecessary.
Applied to files:
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx
📚 Learning: 2024-11-04T13:42:03.737Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/components/ActionButton/Modal/EvidenceUpload.tsx:74-82
Timestamp: 2024-11-04T13:42:03.737Z
Learning: In `web/src/components/ActionButton/Modal/EvidenceUpload.tsx`, the `uploadFile` function already manages error handling and logging, so additional error handling after calling it is unnecessary.
Applied to files:
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Applied to files:
web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts
🧬 Code graph analysis (4)
web/src/pages/SubmitItem/ItemField/FieldInput/NumberInput.tsx (3)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)
LANDSCAPE_WIDTH_CALC(1-1)
web/src/pages/SubmitItem/ItemField/FieldInput/LinkInput.tsx (3)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)
LANDSCAPE_WIDTH_CALC(1-1)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (2)
web/src/utils/index.ts (1)
cn(44-46)web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (2)
MARGIN_BOTTOM_CALC(2-2)LANDSCAPE_WIDTH_CALC(1-1)
web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (3)
web/src/pages/SubmitItem/ItemField/FieldInput/index.tsx (1)
IFieldInput(14-17)web/src/utils/index.ts (1)
cn(44-46)web/src/pages/SubmitItem/ItemField/FieldInput/constants.ts (1)
LANDSCAPE_WIDTH_CALC(1-1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (2)
web/src/pages/SubmitItem/ItemField/FieldInput/ImageInput.tsx (1)
31-42: Verify intentional width difference for FileUploader.This component uses
w-[84vw]while other field inputs (LinkInput, NumberInput, LongTextInput) usew-[80vw]. Is this 4vw difference intentional for the FileUploader component, or should it be consistent?If consistent width is desired, apply this diff:
- "w-[84vw]", + "w-[80vw]",web/src/pages/SubmitItem/ItemField/FieldInput/LongTextInput.tsx (1)
8-23: LGTM! Clean migration to TextArea component.The refactor correctly migrates from styled-components to the UI library's TextArea component with proper responsive styling. The handleChange implementation correctly passes values through without blocking user input.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (6)
web/src/pages/SubmitList/ListParameters/ListPreview/ListPageDisplay.tsx (1)
15-16: Consider using Tailwind's responsive variants instead of mixing inline styles.The code mixes inline
style={{ gap: responsiveSize(32, 24) }}with Tailwind utility classes. Tailwind v4 provides responsive variants (lg:gap-8,gap-6, etc.) and arbitrary values (gap-[32px]) to handle responsive spacing without inline styles. This approach would be more consistent with the Tailwind migration.Example refactor using responsive variants:
- <div className="flex flex-col" style={{ gap: responsiveSize(32, 24) }}> + <div className="flex flex-col gap-6 lg:gap-8">Note: Adjust the exact gap values to match your breakpoint requirements (based on learnings,
lgis 900px in your setup).web/src/pages/SubmitList/ListParameters/ListPreview/index.tsx (1)
17-21: Consider using Tailwind's responsive variants instead of mixing inline styles.Similar to the issue in
ListPageDisplay.tsx, this code mixes inlineresponsiveSize()calls with Tailwind utilities. Tailwind v4 provides responsive variants and arbitrary values that would be more idiomatic.Example refactor:
- style={{ - marginBottom: responsiveSize(0, 16), - paddingBlock: responsiveSize(24, 48), - paddingInline: responsiveSize(24, 32), - }} + style={{ + marginBottom: 0, + }} + className={clsx( + "relative flex flex-col gap-8 w-full h-auto min-h-[100px]", + "border-dashed border-klerosUIComponentsPrimaryBlue bg-klerosUIComponentsMediumBlue", + "py-6 px-6 lg:py-12 lg:px-8 lg:mb-4" + )}Or remove the inline style entirely if
marginBottom: 0is the default.web/src/pages/SubmitList/ListParameters/ListPreview/HomePageDisplay.tsx (1)
13-13: Consider using Tailwind responsive gap utilities for consistency.The inline
styleforgapmixes Tailwind classes with inline styles. Since the project has migrated to Tailwind v4 with custom breakpoints configured, consider using Tailwind's responsive gap utilities instead.Apply this diff to use Tailwind gap utilities:
- <div className="flex flex-col" style={{ gap: responsiveSize(32, 24) }}> + <div className="flex flex-col gap-6 lg:gap-8">Note: Adjust the spacing values (
gap-6= 24px,gap-8= 32px) if the Tailwind spacing scale differs. If the exact pixel values are required, use arbitrary values:gap-[24px] lg:gap-[32px].web/src/pages/SubmitList/Timeline.tsx (1)
33-33: Consider using the cn utility for consistency.While the className string is correct, consider using the
cnutility (already used in other components like Title.tsx) for better consistency and maintainability across the codebase.- return <Steps className="hidden lg:absolute lg:flex lg:left-[2%] lg:h-[360px]" {...{ items, currentItemIndex }} />; + return <Steps className={cn("hidden lg:absolute lg:flex lg:left-[2%] lg:h-[360px]")} {...{ items, currentItemIndex }} />;Based on learnings
web/src/pages/SubmitList/constants.ts (1)
1-5: Document the fluid responsive calculation formulas.The calc expressions implement fluid responsive sizing, but the formulas are complex and lack documentation. Consider adding comments to explain the interpolation ranges for future maintainability.
export const BASE_CONTAINER_STYLE = "flex flex-col items-center gap-8 w-[84vw]"; + +// Fluid width: interpolates from 442px to 700px between 900px and 1250px viewport width export const BASE_CONTAINER_LANDSCAPE_WIDTH_CALC = "lg:w-[calc(442px+(700-442)*(min(max(100vw,900px),1250px)-900px)/(1250-900))]"; + +// Fluid margin-bottom: interpolates from 150px to 72px between 375px and 1250px viewport width export const FILE_UPLOADER_MARGIN_BOTTOM_CALC = "mb-[calc(150px+(72-150)*(min(max(100vw,375px),1250px)-375px)/(1250-375))]";web/src/pages/SubmitList/ListParameters/LogoUpload.tsx (1)
60-61: Consider the fragility of the[&_small]selector pattern.The
[&_small]:whitespace-pre-line [&_small]:text-startselectors target child<small>elements within theFileUploadercomponent. This couples your styling to the internal DOM structure of@kleros/ui-components-library.If the library changes its markup (e.g., removes
<small>tags or alters the hierarchy), these styles will silently break. Consider:
- Using the library's className props if available for message elements
- Requesting the library to expose className props for better styling control
- Documenting this dependency for future maintenance
The pattern is intentional (also used in Policy.tsx line 57), but be aware of the maintenance cost.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (14)
web/src/pages/SubmitList/Header.tsx(1 hunks)web/src/pages/SubmitList/ListParameters/Description.tsx(1 hunks)web/src/pages/SubmitList/ListParameters/ListPreview/HomePageDisplay.tsx(2 hunks)web/src/pages/SubmitList/ListParameters/ListPreview/ListPageDisplay.tsx(2 hunks)web/src/pages/SubmitList/ListParameters/ListPreview/index.tsx(1 hunks)web/src/pages/SubmitList/ListParameters/LogoUpload.tsx(3 hunks)web/src/pages/SubmitList/ListParameters/Policy.tsx(3 hunks)web/src/pages/SubmitList/ListParameters/Title.tsx(1 hunks)web/src/pages/SubmitList/NavigationButtons/NextButton.tsx(1 hunks)web/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx(1 hunks)web/src/pages/SubmitList/NavigationButtons/SubmitListButton.tsx(1 hunks)web/src/pages/SubmitList/NavigationButtons/index.tsx(1 hunks)web/src/pages/SubmitList/Timeline.tsx(1 hunks)web/src/pages/SubmitList/constants.ts(1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/layout/index.tsx:15-28
Timestamp: 2025-10-24T21:25:59.174Z
Learning: In Tailwind v4, when using CSS variables from external libraries like kleros/ui-components-library, add the `source` directive in global.css to tell Tailwind to scan and generate utility classes from those variables. Example: `source "../node_modules/kleros/ui-components-library";`
📚 Learning: 2024-11-04T13:33:39.755Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/pages/Settings/index.tsx:18-26
Timestamp: 2024-11-04T13:33:39.755Z
Learning: In `web/src/pages/Settings/index.tsx`, the parent route handles the default `/settings` route, error boundaries, and loading states, so it's not necessary to include them in this component.
Applied to files:
web/src/pages/SubmitList/NavigationButtons/index.tsx
📚 Learning: 2025-11-14T22:12:39.974Z
Learnt from: kyrers
Repo: kleros/curate-v2 PR: 89
File: web/src/styles/breakpoints.ts:1-1
Timestamp: 2025-11-14T22:12:39.974Z
Learning: In the kleros/curate-v2 repository, the kleros/ui-components-library overrides Tailwind's lg breakpoint to 900px (not the default 1024px). The LG_BREAKPOINT constant in web/src/styles/breakpoints.ts is set to 900 to match this override. This configuration is imported via the source directive in global.css.
Applied to files:
web/src/pages/SubmitList/constants.ts
📚 Learning: 2024-11-04T13:31:54.080Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx:72-96
Timestamp: 2024-11-04T13:31:54.080Z
Learning: In the React TypeScript component `FormContactDetails` in `web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/index.tsx`, error handling and user feedback are implemented within the `addUser` and `updateEmail` functions, which display toasts to the user.
Applied to files:
web/src/pages/SubmitList/ListParameters/Title.tsx
📚 Learning: 2024-11-04T13:41:01.846Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/layout/Header/navbar/Menu/Settings/Notifications/FormContactDetails/EmailVerificationInfo.tsx:67-80
Timestamp: 2024-11-04T13:41:01.846Z
Learning: In React components, when a button is used within a form, calling `e.preventDefault()` in the event handler is necessary to prevent the default form submission, even when using an `onClick` handler.
Applied to files:
web/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx
📚 Learning: 2024-11-04T13:42:03.737Z
Learnt from: Harman-singh-waraich
Repo: kleros/curate-v2 PR: 65
File: web/src/components/ActionButton/Modal/EvidenceUpload.tsx:74-82
Timestamp: 2024-11-04T13:42:03.737Z
Learning: In `web/src/components/ActionButton/Modal/EvidenceUpload.tsx`, the `uploadFile` function already manages error handling and logging, so additional error handling after calling it is unnecessary.
Applied to files:
web/src/pages/SubmitList/ListParameters/LogoUpload.tsx
🧬 Code graph analysis (5)
web/src/pages/SubmitList/ListParameters/Description.tsx (3)
web/src/context/SubmitListContext.tsx (1)
useSubmitListContext(123-123)web/src/utils/index.ts (1)
cn(44-46)web/src/pages/SubmitList/constants.ts (2)
BASE_CONTAINER_STYLE(1-1)BASE_CONTAINER_LANDSCAPE_WIDTH_CALC(2-3)
web/src/pages/SubmitList/ListParameters/Title.tsx (3)
web/src/context/SubmitListContext.tsx (1)
useSubmitListContext(123-123)web/src/utils/index.ts (1)
cn(44-46)web/src/pages/SubmitList/constants.ts (2)
BASE_CONTAINER_STYLE(1-1)BASE_CONTAINER_LANDSCAPE_WIDTH_CALC(2-3)
web/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx (1)
web/src/utils/index.ts (1)
isEmpty(13-13)
web/src/pages/SubmitList/ListParameters/LogoUpload.tsx (2)
web/src/utils/index.ts (1)
cn(44-46)web/src/pages/SubmitList/constants.ts (3)
BASE_CONTAINER_STYLE(1-1)BASE_CONTAINER_LANDSCAPE_WIDTH_CALC(2-3)FILE_UPLOADER_MARGIN_BOTTOM_CALC(4-5)
web/src/pages/SubmitList/ListParameters/Policy.tsx (2)
web/src/utils/index.ts (2)
cn(44-46)getFileUploaderMsg(23-42)web/src/pages/SubmitList/constants.ts (3)
BASE_CONTAINER_STYLE(1-1)BASE_CONTAINER_LANDSCAPE_WIDTH_CALC(2-3)FILE_UPLOADER_MARGIN_BOTTOM_CALC(4-5)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Redirect rules - curate-v2
- GitHub Check: Header rules - curate-v2
- GitHub Check: Pages changed - curate-v2
🔇 Additional comments (18)
web/src/pages/SubmitList/ListParameters/ListPreview/HomePageDisplay.tsx (1)
14-14: The custom color class is properly configured and working.The
text-klerosUIComponentsPrimaryBlueutility class is correctly generated by Tailwind v4 from the CSS variables exported by@kleros/ui-components-library(v3.6.0). The@sourcedirective in global.css is properly configured to scan the library for CSS variables, and this pattern is used successfully across 20+ files in the codebase without issues.web/src/pages/SubmitList/NavigationButtons/NextButton.tsx (1)
43-43: LGTM! Clean API migration.The prop rename from
disabledtoisDisabledcorrectly aligns with the @kleros/ui-components-library v3 API.web/src/pages/SubmitList/NavigationButtons/SubmitListButton.tsx (2)
232-232: LGTM! Correct prop migration.The
isDisabledprop correctly replaces the deprecateddisabledprop, consistent with the library v3 API.
231-233: I'll search for the Button component API documentation for @kleros/ui-components-library v3.6.0.Let me search more specifically for the Button component's TypeScript types and props for this library.
Let me search more directly for the Kleros library Button component.
Based on my web search attempts, I was unable to find specific documentation for the
@kleros/ui-components-libraryv3.6.0 Button component's Icon prop API in publicly available sources. The GitHub repository and NPM package listings do not expose detailed TypeScript types or prop documentation in search results.Unable to verify Icon prop API via web search. The @kleros/ui-components-library v3.6.0 Button component's Icon prop specification is not documented in publicly available sources. You need to verify this directly by:
- Checking the installed package types:
node_modules/@kleros/ui-components-library/dist/components/Buttonor similar path- Reviewing the library's TypeScript definition files (.d.ts)
- Consulting the library's Storybook or GitHub releases page for v3.6.0
- Running a quick test to confirm
Icon={CheckCircle}compiles without errorsweb/src/pages/SubmitList/NavigationButtons/PreviousButton.tsx (1)
21-27: LGTM! Clean migration to utility classes.The Button component correctly:
- Uses conditional className logic to toggle visibility based on
prevRoute- Migrates to the
isDisabledprop- Preserves the original hide/show and navigation behavior
web/src/pages/SubmitList/NavigationButtons/index.tsx (1)
12-15: LGTM! Straightforward styled-components removal.The replacement of the styled Container with a plain div using Tailwind utility classes is clean and maintains the same layout behavior.
web/src/pages/SubmitList/Header.tsx (1)
8-8: LGTM! Clean styled-components removal.The h1 element with Tailwind utilities correctly replaces the styled Container. The responsive width classes (
w-[84vw] lg:w-auto) maintain the original behavior.Based on learnings
web/src/pages/SubmitList/ListParameters/Title.tsx (2)
17-29: Excellent use of shared constants and cn utility.The migration to TextField with shared layout constants (
BASE_CONTAINER_STYLE,BASE_CONTAINER_LANDSCAPE_WIDTH_CALC) and thecnutility promotes consistency and maintainability across the SubmitList feature.
13-15: TextField onChange API usage is correct and verified.The handler signature in Title.tsx properly receives a
value: stringparameter directly from the @kleros/ui-components-library TextField component. This is confirmed by consistent usage patterns throughout the codebase—for example, FormContact.tsx usesonChange={(value) => setContactInput(value)}, confirming that the onChange handler receives the value directly, not an event object.The implementation is compatible with @kleros/ui-components-library v3.6.0 and follows the library's documented API pattern.
web/src/pages/SubmitList/ListParameters/LogoUpload.tsx (2)
9-15: LGTM: Imports properly support the Tailwind migration.The imports correctly bring in the
cnutility for class composition and centralized layout constants, supporting the migration away from styled-components.
58-58: LGTM: Container properly migrated to Tailwind classes.The container correctly uses
cn()to compose the base container style with the landscape width calculation.web/src/pages/SubmitList/ListParameters/Description.tsx (3)
8-8: LGTM: Constants import is correct.Properly imports the centralized layout constants for consistent styling across SubmitList pages.
12-14: LGTM: Handler correctly updated for TextField API.The
handleWritesignature properly changed from accepting a React ChangeEvent to accepting a string value directly, aligning with the newTextFieldcomponent'sonChangeAPI.
16-32: LGTM: Component structure cleanly migrated to Tailwind.The layout properly uses centralized constants for the container and applies Tailwind utilities for the inner structure. The TextField and InfoCard are correctly configured.
web/src/pages/SubmitList/ListParameters/Policy.tsx (4)
10-16: LGTM: Imports are correct and consistent.The imports properly support the Tailwind migration with the correct path (
src/utilswithout tilde) and centralized layout constants.
41-41: LGTM: Container properly migrated to Tailwind classes.The container correctly uses
cn()to compose layout constants, consistent with the other SubmitList pages.
43-55: LGTM: Label properly migrated to use className.The label correctly uses
className="w-full"instead of styled-components, maintaining the same content and Link structure.
56-57: LGTM: FileUploader properly migrated to Tailwind classes.The FileUploader correctly uses
cn()to compose classes including the[&_small]selector pattern. Note that the same fragility concern regarding the[&_small]selector mentioned in the LogoUpload.tsx review (lines 60-61) applies here as well.
Resolves #88.
PR-Codex overview
This PR focuses on refactoring the codebase by removing styled-components, replacing them with Tailwind CSS classes, and updating various components to improve performance and maintainability.
Detailed summary
styled-componentsand replaced with Tailwind CSS classes.disabledtoisDisabled.Summary by CodeRabbit
Chores
New Features
Refactor
Other